#ifndef TABU_METHOD_H
#define TABU_METHOD_H

//Tabu search dla produktu z okreslonymi podproduktami i ich dostawcami. Uzwglednione:
//-kryterium stopu: iteracyjne badz dluzszy brak poprawy rozwiazania
//-lista tabu krotko i dlugoterminowa(eliminowanie pozostanie w lokalnym minimum)
//-rozwiazanie pierwotne losowe/wybrane przez uzytkownika
//-opoznienia czasowe i funkcja kary/bonifikaty,

#include <QMap>
#include <QVector>
#include <QQueue>       //for FIFO
#include <QGlobal.h>    //for rand()
#include <QTime>
#include "database.h"
#include "database.h"

class tabu_search
{
private:
    int deadline;
    int quantity;
    int products;
    int productionPerDay;
    Database* base;
    int iter;
    int iterImprov;
    int improv;
    int tabuLength;
    QQueue<QMap>tabuList;
    int iterJump;
    QVector<int> firstSolution;
    QVector<int> bestSolution;
    QMap<int, QVector> solutions;//number of following correct solution, vector of following correct solution
    QMap<int, float> values; //number of following correct solution, following cost
    int kara;
    int nagroda;
    int numberOfCorrectSolutions;


    void AddSolution(QVector<int> tempSolution);                // adds a solution if it is permittable
    bool tabu_search::StoppingCondition(int iterations, int improvement);   //checks whether to continue searching
    QVector<int> FindFirstSolution();                           // decides what a first solution will be(given or random)
    QVector<int> GenerateSolution();                            //generates a random solution
    QVector<int> tabu_search::GenerateNeighborhood(QVector<int> bestSolution); //generates neighbourhood
    int Assess(int iter);                                        //ocena rozwiazania, jesli -1 to rozw niedopuszczalne
    int TotalProductionDelay(QVector <int> tempSolution);        //obliczenie opoznienia rozpoczecia produkcji
    int ItemDelay(int quantityPerItem, int productionTime,  int provideDelay);  //opoznienie spowodowane konkretnym podproduktem
    int DaysAmount(float quantityPerItem, int quantityAvailablePerDay);         //ilosc dni wzgledem dostawy/zapotrzebowania/produkcji

public:

    tabu_search();
    tabu_search(DataBase *_base,
                int _iter,
                int _iterImprov,
                int _improv,
                int _tabuList,
                int _tabuLength,
                int _iterJump,
                QVector<int> _firstSolution,
                int _kara,
                int _nagroda);

    void ConductSearch();                   //conducts tabu search
    int NumberOfCorrectSolutions();         //number of permitted solutions found
    int BestValue(int correctSolutionFound);// best solution value for arguments equal or less than number of correct solutions
    QMap<int, QVector> Solutions();         //Qmap: number of solution, vector of solution(last n+1 place is total days)
    QMap<int, float> Values();              //Qmap: number of solution, obtained value
};

/*
Rezultatem macierz o wymiarze 2xN+1 gdzie pierwszy wiersz to kolejni dostawcy,
a drugi to ilosc danego towaru; ostatnia kolumna to opoznienie oraz uzyskany koszt.
************************************************************************************
Argumenty:
deadline - termin wykonania produktu
quantity - ilosc produktu
products - ilosc potrzebnych podproduktow
productionPerDay - produkcja na dzien
Base  - wskaznik na obiekt bedacy produkowanym dobrem
iter  - kryterium stopu to ilosc iteracji iter, gdy uwzglednione tylko kryterium poprawy: iter=0
iterImprov-ilosc krokow w ktorych powinna nastapic jakakolwiek poprawa
improv- kryterium stopu to brak poprawy improv(%), gdy tylko kryterium iteracji: improv=0
tabuLength - dlugosc listy tabu
tabuList- lista tabu(FIFO), klucz to podprodukt, wartosc to zabroniony dostawca
iterJump - ilosc iteracji dla ktorych nie majac poprawy rozwiazania opuszczamy sasiedztwo
            zapobiega pozostaniiu w minimum lokalnym, gdy pomijamy ten parametr, iterJump=0
firstSolution - sugerowane rozwiazanie poczatkowe, gdy wszystkie(pierwszy) elementy=-1 to wybierane losowo
bestSolution - rozwiazanie najlepsze
solutions - struktura z kolejno otrzymanymi rozwiazaniami
values  - struktura z kolejno otrzymanymi wynikami funkcji celu
kara - kara za kazdy dzien zwloki, gdy kara=0 nie mozna przekroczyc terminu zlecenia
nagroda - dodatkowy zysk za kazdy dzien wykonania zlecenia przed terminem, gdy zysk=0 to nie ma sie co spieszyc
numberOfCorrectSolutions - otrzymane rozwiazania dopuszczalne(rozne od iteracji gdy nie mozna przekroczyc terminu)
*/


#endif // TABU_METHOD_H
